'use strict';

var utils = require('./../utils');
var settle = require('./../core/settle');
var buildURL = require('./../helpers/buildURL');
var isURLSameOrigin = require('./../helpers/isURLSameOrigin');
var createError = require('../core/createError');

module.exports = function uniRequestAdapter(config) {
  // 返回一个promise
  return new Promise(function(resolve, reject) {

    let requestData = config.data;
    let withCredentials = false;
    let responseType = 'text';
    const requestHeaders = config.headers;

    if (utils.isFormData(requestData)) {
      delete requestHeaders['Content-Type']; // Let the browser set it
    }
    // HTTP basic authentication
    if (config.auth) {
      var username = config.auth.username || '';
      var password = config.auth.password || '';
      requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password);
    }
    // Add xsrf header
    // This is only done if running in a standard browser environment.
    // Specifically not if we're in a web worker, or react-native.
    if (utils.isStandardBrowserEnv()) {
      var cookies = require('./../helpers/cookies');

      // Add xsrf header
      var xsrfValue = (config.withCredentials || isURLSameOrigin(config.url)) && config.xsrfCookieName ?
        cookies.read(config.xsrfCookieName) :
        undefined;

      if (xsrfValue) {
        requestHeaders[config.xsrfHeaderName] = xsrfValue;
      }
    }

    // Add withCredentials to request if needed
    if (config.withCredentials) {
      withCredentials = true;
    }

    // 如果需要指定responseType
    // Add responseType to request if needed
    if (config.responseType) {
      try {
        responseType = config.responseType;
      } catch (e) {
        // Expected DOMException thrown by browsers not compatible XMLHttpRequest Level 2.
        // But, this can be suppressed for 'json' type as it can be parsed by default 'transformResponse' function.
        if (config.responseType !== 'json') {
          throw e;
        }
      }
    }

    if (requestData === undefined) {
      requestData = null;
    }

    let request = uni.request({
      url: buildURL(config.url, config.params, config.paramsSerializer),
      method: config.method.toUpperCase(),
      timeout: config.timeout,
      data: requestData,
      header: requestHeaders,
      withCredentials,
      responseType,
      success: (data, status, headers) => {
        // request不存在, 直接结束
        if (!request) {
          return;
        }
        const response = {
          data,
          status,
          statusText: `${status}`,
          headers,
          config: config,
          request: request
        };
        // 根据响应状态码来确定请求的promise的结果状态(成功/失败)
        settle(resolve, reject, response);
        // 将请求对象赋空
        request = null;
      }
    });
    // 如果配置了cancelToken
    if (config.cancelToken) {
      // 指定用于中断请求的回调函数
      config.cancelToken.promise.then(function onCanceled(cancel) {
        if (!request) {
          return;
        }
        // 中断请求
        request.abort();
        // 让请求的promise失败
        reject(cancel);
        // Clean up request
        request = null;
      });
    }

    // 绑定请求中断监听
    request.onabort = function handleAbort() {
      if (!request) {
        return;
      }
      // reject promise, 指定aborted的error
      reject(createError('Request aborted', config, 'ECONNABORTED', request));

      // Clean up request
      request = null;
    };

    // Handle low level network errors
    request.onerror = function handleError() {
      // Real errors are hidden from us by the browser
      // onerror should only fire if it's a network error
      reject(createError('Network Error', config, null, request));

      // Clean up request
      request = null;
    };

    // Handle timeout
    request.ontimeout = function handleTimeout() {
      reject(createError('timeout of ' + config.timeout + 'ms exceeded', config, 'ECONNABORTED',
        request));
      // Clean up request
      request = null;
    };

    // // 绑定下载进度的监听
    // // Handle progress if needed
    // if (typeof config.onDownloadProgress === 'function') {
    //   request.addEventListener('progress', config.onDownloadProgress);
    // }
    //
    // // 绑定上传进度的监听
    // // Not all browsers support upload events
    // if (typeof config.onUploadProgress === 'function' && request.upload) {
    //   request.upload.addEventListener('progress', config.onUploadProgress);
    // }
  });
};
